#pragma once

#include "ip_context.hpp"
#include "ip_packet.hpp"
#include "limbo/details/traits.hpp"
#include "opts.h"

namespace limbo::ip {

template <typename NextState, int options = 0> struct State {
  using Context = IpContext<State>;
  using Packet = IpPacket<State>;
  using LowerState = NextState;
  using LowerPacket = details::lower_packet_t<LowerState>;
  static constexpr int opts = options;

  Result recv(Chunk buff, LowerState *lower_state) {
    return packet.recv(buff, *this, lower_state);
  }

  void init(uint16_t next_id_ = 0) { next_id = next_id_; }

  Packet &get_parsed() { return packet; }

  inline bool select(const LowerPacket *packet) {
    return is_ip_packet(*packet);
  }

  Packet packet;
  uint16_t next_id = 0;
};

} // namespace limbo::ip
